/**
 LhapdfDistribution.cxx

 \file
 Implementation of class LhapdfDistribution.

 \author Thomas Burton 
 \date 3/9/12
 \copyright 2012 BNL. All rights reserved.
*/

#include "tppmc/LhapdfDistribution.h"

#include <cmath>
#include <iostream>
#include <sstream>

#include <LHAPDF/LHAPDF.h>

#include "tppmc/Particle.h"

namespace tppmc {

   unsigned LhapdfDistribution::objectCount_(0);

   LhapdfDistribution::LhapdfDistribution()
   : objectNumber_(0)
   , lhapdfSetId_(10800)
   , lhapdfSetMember_(0) {
   }

   LhapdfDistribution::LhapdfDistribution(unsigned setId, unsigned setMember)
   : objectNumber_( ++LhapdfDistribution::objectCount_ )
   , lhapdfSetId_(setId)
   , lhapdfSetMember_(setMember) {
   }

   int
   LhapdfDistribution::Initialise() {
      LHAPDF::initPDFSet( getLhapdfSetNumber(),
                         getLhapdfSetId(),
                         getLhapdfSetMember() );
      return 0;
   }

   void
   LhapdfDistribution::Evaluate(const Parton& parton, double Q2,
                                PartonContent& fx) const {
      static LHAPDF::Flavour flavours[13] = {
         LHAPDF::TBAR, LHAPDF::BBAR, LHAPDF::CBAR,
         LHAPDF::SBAR, LHAPDF::UBAR, LHAPDF::DBAR,
         LHAPDF::GLUON,
         LHAPDF::DOWN, LHAPDF::UP, LHAPDF::STRANGE,
         LHAPDF::CHARM, LHAPDF::BOTTOM, LHAPDF::TOP
      };
      
      for( int i(0); i < 13; ++i ) {
         fx[flavours[i]] = evaluate(parton, Q2, flavours[i]);
      } // for
   }

   double LhapdfDistribution::evaluate(const Parton& point, double Q2,
                                       LHAPDF::Flavour f) const {
      double x = point.x;
      double Q = ::sqrt( Q2 );
      return LHAPDF::xfx( getLhapdfSetNumber(), x, Q, f ) / x;
   }
   
   double LhapdfDistribution::GetXMin() const {
      return LHAPDF::getXmin( getLhapdfSetNumber() );
   }

   double LhapdfDistribution::GetXMax() const {
      return LHAPDF::getXmax( getLhapdfSetNumber() );
   }

   double LhapdfDistribution::GetQ2Min() const {
      return LHAPDF::getQ2min( getLhapdfSetNumber() );
   }

   double LhapdfDistribution::GetQ2Max() const {
      return LHAPDF::getQ2max( getLhapdfSetNumber() );
   }

   bool LhapdfDistribution::Supports(const Parton& parton) const {
      return parton.Type() >= LHAPDF::TBAR and parton.Type() <= LHAPDF::PHOTON;
   }

   std::string LhapdfDistribution::Name() const {
      std::ostringstream oss;
      oss << "LHAPDF set " << getLhapdfSetId() << " member " <<
      getLhapdfSetMember();
      return oss.str();
   }
} // namespace tppmc
